package myJs

import myJs.myPkg.jquery._

import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}
import Utils._
import org.scalajs.dom.ext.Ajax
import shared.Implicits._
import scalatags.Text.all._

import scala.scalajs.js.JSON
import scala.scalajs.js.Dynamic.{global => g}
import scala.concurrent.ExecutionContext.Implicits.global
import myJs.Implicits._
import myJs.myPkg.{ColumnOptions, DatepickerOptions, MyFetch, TableOptions}
import myJs.myPkg.plotly._
import org.scalajs.dom
import org.scalajs.dom.document
import shared.highcharts.config.XAxis

import scala.collection.immutable.SeqMap
import myJs.Implicits._

import scala.scalajs.js.JSConverters._
import com.softwaremill.quicklens._

/**
 * Created by yz on 2019/4/15
 */
@JSExportTopLevel("PredictResult")
object PredictResult {

  var idStr: String = _
  val tableId = "table"

  @JSExport("init")
  def init = {
    //    showResult("368")
    dateInit
    registerEvent
  }

  def registerEvent = {
    $(document.body).on("change", s"#form .myDatepicker", "", (y: dom.Element) => {
      val startDate = Tool.getInputByName("startDate").myVal
      val endDate = Tool.getInputByName("endDate").myVal
      linearPlot(idStr, startDate, endDate)
    })
  }

  def dateInit = {
    val options = DatepickerOptions.format("yyyy-mm-dd").autoclose(true).forceParse(true).language("zh-CN")
    $(".myDatepicker").datepicker(options)
  }

  def linearPlot(id: String, startDate: String = "", endDate: String = "") = {
    val url = g.jsRoutes.controllers.PredictController.getLinearPlotData().url.toString
    MyFetch.get(url = s"${url}?missionId=${id}&startDate=${startDate}&endDate=${endDate}",
      headers = Map("Content-Type" -> "application/json")).map { any =>
      val rs = any.toJDJAn
      val array = rs("array").toJArJDJAn
      val dTick = rs.myGet("dTick")
      val colors = rs("colors").toJArS.toList
      array.zipWithIndex.foreach { case (dict, i) =>
        val trace = Scatter(
          x = dict("x").toJArS.toList,
          y = dict("y").toJArS.toList,
          marker = Marker(
            color = colors
          ),
          `type` = "scatter"
        )
        val plotData = List(trace)
        val tickFormat = "%Y/%m/%d"
        val baseLayout = Layout(
          xaxis = Axis(
            tickformat = tickFormat,
            dtick = dTick,
            fixedrange = true,
            tickangle = -45,
            nticks = 5,
            zeroline = false
          ),
          hovermode = HoverMode.closest,
          yaxis = Axis(
            fixedrange = true,
            title = dict.myGet("yTitle"),
            zeroline = false
          ),
          title = dict.myGet("title"),
          margin = Margin(b = 90, l = 70, t = 70, r = 10),
        )

        implicit def undefOrQuicklensFunctor[A]: QuicklensFunctor[js.UndefOr, A] with QuicklensSingleAtFunctor[js.UndefOr, A] =
          new QuicklensFunctor[js.UndefOr, A] with QuicklensSingleAtFunctor[js.UndefOr, A] {
            override def map(fa: js.UndefOr[A])(f: A => A): js.UndefOr[A] = fa.map(f)

            override def at(fa: js.UndefOr[A])(f: A => A): js.UndefOr[A] = fa.map(f).get

            override def atOrElse(fa: js.UndefOr[A], default: => A)(f: A => A): js.UndefOr[A] = fa.orElse(default).map(f)

            override def index(fa: js.UndefOr[A])(f: A => A): js.UndefOr[A] = fa.map(f)
          }

        val layout=if(i==0){
          baseLayout.modify(_.yaxis.at.dtick).setTo(rs.myGet("ageDTick"))
        }else baseLayout

        val config = Config(displayModeBar = false)

        val gd = Plotly.newPlot(s"svg${i}", plotData, layout, config)

        val base64Layout = layout.modify(_.xaxis.at.tickfont.atOrElse(Font()).size).setTo(25)
          .modify(_.xaxis.at.gridwidth).setTo(3)
          .modify(_.yaxis.at.tickfont.atOrElse(Font()).size).setTo(25)
          .modify(_.yaxis.at.titlefont.atOrElse(Font()).size).setTo(30)
          .modify(_.yaxis.at.gridwidth).setTo(3)
          .modify(_.margin.at.b).setTo(150)
          .modify(_.margin.at.l).setTo(110)
          .modify(_.font.atOrElse(Font()).size).setTo(25)
        val base64PlotData = plotData.modify(_.at(0).marker.at.size).setTo(15)
        Plotly.toImage(options = ImageOptions(data = base64PlotData, layout = base64Layout), layout = ImageLayout()).
          toFuture.foreach { x =>
          Tool.getInputByName(s"base64${i}").`val`(x)
        }
      }
    }.timeoutDeal

  }

  @JSExport("showResult")
  def showResult(id: String) = {
    $("#result").hide()
    $("#mode2,#mode3").hide()
    val index = layer.load(1, layerOptions.shade(js.Array("0.1", "#fff")))
    val url = g.jsRoutes.controllers.PredictController.predictResult().url.toString
    MyFetch.get(url = s"${url}?missionId=${id}",
      headers = Map("Content-Type" -> "application/json")).map { data =>
      val rs = data.asInstanceOf[js.Dictionary[js.Any]]
      layer.close(index)
      $("#showSampleId").text(rs.myGet("sampleId"))
      $("#showName").text(rs.myGet("name"))
      g.missionJson = rs("mission")
      g.extraDataJson = rs("extraData")
      idStr = id
      linearPlot(id)
      $("#result").show()
      val target_top = $("#result").offset().top
      $("html,body").animate(js.Dictionary("scrollTop" -> target_top), JQueryAnimationSettings.duration(800))
    }.timeoutDeal(index)

  }

}
